import { Provide, Inject, InjectClient } from '@midwayjs/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager';
import { GoodsInfoEntity } from '../entity/info';
import { GoodsUserPriceStrategyEntity } from '../entity/userPriceStrategy';
import { GoodsPriceEntity } from '../entity/price';
import { GoodsUserProductPriceEntity } from '../entity/userPrice';

/**
 * 价格计算服务
 */
@Provide()
export class GoodsPriceCalculatorService {
  @InjectEntityModel(GoodsInfoEntity)
  goodsInfoEntity: Repository<GoodsInfoEntity>;

  @InjectEntityModel(GoodsUserPriceStrategyEntity)
  userPriceStrategyEntity: Repository<GoodsUserPriceStrategyEntity>;

  @InjectEntityModel(GoodsPriceEntity)
  priceEntity: Repository<GoodsPriceEntity>;

  @InjectEntityModel(GoodsUserProductPriceEntity)
  userProductPriceEntity: Repository<GoodsUserProductPriceEntity>;

  @InjectClient(CachingFactory, 'default')
  midwayCache: MidwayCache;

  /**
   * 计算用户对商品的最终价格
   * @param userId 用户ID
   * @param goodsId 商品ID
   * @param quantity 购买数量
   * @returns 最终价格
   */
  async calculatePrice(userId: number, goodsId: number, quantity: number = 1): Promise<number> {
    // 缓存键
    const cacheKey = `goods_price:${userId}:${goodsId}:${quantity}`;
    
    // 尝试从缓存获取
    try {
      const cachedPrice = await this.midwayCache.get(cacheKey);
      if (cachedPrice) {
        return parseFloat(cachedPrice as string);
      }
    } catch (error) {
      console.warn('获取价格缓存失败:', error);
    }

    // 1. 获取商品基础信息
    const goodsInfo = await this.goodsInfoEntity.findOne({
      where: { id: goodsId, status: 1 }
    });

    if (!goodsInfo) {
      throw new Error('商品不存在或已下架');
    }

    let finalPrice = parseFloat(goodsInfo.price.toString());

    // 2. 检查用户专属价格（优先级最高）
    const userProductPrice = await this.getUserProductPrice(userId, goodsId);
    if (userProductPrice) {
      finalPrice = parseFloat(userProductPrice.specialPrice.toString());
    } else {
      // 3. 检查价格层级
      const tierPrice = await this.getTierPrice(userId, goodsId, quantity);
      if (tierPrice) {
        finalPrice = parseFloat(tierPrice.price.toString());
      } else {
        // 4. 应用用户价格策略
        const strategyPrice = await this.applyUserPriceStrategy(userId, finalPrice);
        if (strategyPrice) {
          finalPrice = strategyPrice;
        }
      }
    }

    // 缓存结果（5分钟）
    try {
      await this.midwayCache.set(cacheKey, finalPrice.toString(), 300);
    } catch (error) {
      console.warn('设置价格缓存失败:', error);
    }

    return finalPrice;
  }

  /**
   * 获取用户专属价格
   */
  private async getUserProductPrice(userId: number, goodsId: number): Promise<GoodsUserProductPriceEntity | null> {
    const now = new Date();
    return await this.userProductPriceEntity.findOne({
      where: {
        userId,
        goodsId,
        status: 1,
      },
      order: {
        priority: 'DESC',
        createTime: 'DESC'
      }
    });
  }

  /**
   * 获取价格层级价格
   */
  private async getTierPrice(userId: number, goodsId: number, quantity: number): Promise<GoodsPriceEntity | null> {
    // 获取用户策略类型
    const userStrategy = await this.userPriceStrategyEntity.findOne({
      where: { userId, status: 1 }
    });

    if (!userStrategy) {
      return null;
    }

    const now = new Date();
    return await this.priceEntity.findOne({
      where: {
        goodsId,
        priceLevel: userStrategy.strategyType,
        status: 1,
      },
      order: {
        minQuantity: 'DESC'
      }
    });
  }

  /**
   * 应用用户价格策略
   */
  private async applyUserPriceStrategy(userId: number, basePrice: number): Promise<number | null> {
    const now = new Date();
    const userStrategy = await this.userPriceStrategyEntity.findOne({
      where: {
        userId,
        status: 1
      }
    });

    if (!userStrategy) {
      return null;
    }

    // 检查时间有效性
    if (userStrategy.startTime && userStrategy.startTime > now) {
      return null;
    }
    if (userStrategy.endTime && userStrategy.endTime < now) {
      return null;
    }

    const discountRate = parseFloat(userStrategy.discountRate.toString()) / 100;
    let finalPrice = basePrice * discountRate;

    // 检查最低折扣限制
    if (userStrategy.minDiscountRate) {
      const minDiscountRate = parseFloat(userStrategy.minDiscountRate.toString()) / 100;
      const minPrice = basePrice * minDiscountRate;
      if (finalPrice < minPrice) {
        finalPrice = minPrice;
      }
    }

    return finalPrice;
  }

  /**
   * 批量计算商品价格
   */
  async calculateBatchPrices(userId: number, goodsItems: Array<{goodsId: number, quantity: number}>): Promise<Array<{goodsId: number, price: number, quantity: number}>> {
    const results = [];
    
    for (const item of goodsItems) {
      try {
        const price = await this.calculatePrice(userId, item.goodsId, item.quantity);
        results.push({
          goodsId: item.goodsId,
          price,
          quantity: item.quantity
        });
      } catch (error) {
        console.warn(`计算商品${item.goodsId}价格失败:`, error);
        results.push({
          goodsId: item.goodsId,
          price: 0,
          quantity: item.quantity
        });
      }
    }

    return results;
  }

  /**
   * 清除价格缓存
   */
  async clearPriceCache(userId?: number, goodsId?: number): Promise<void> {
    try {
      if (userId && goodsId) {
        // 清除特定用户和商品的缓存
        const pattern = `goods_price:${userId}:${goodsId}:*`;
        await this.clearCacheByPattern(pattern);
      } else if (userId) {
        // 清除特定用户的所有价格缓存
        const pattern = `goods_price:${userId}:*`;
        await this.clearCacheByPattern(pattern);
      } else if (goodsId) {
        // 清除特定商品的所有价格缓存
        const pattern = `goods_price:*:${goodsId}:*`;
        await this.clearCacheByPattern(pattern);
      } else {
        // 清除所有价格缓存
        const pattern = `goods_price:*`;
        await this.clearCacheByPattern(pattern);
      }
    } catch (error) {
      console.warn('清除价格缓存失败:', error);
    }
  }

  /**
   * 根据模式清除缓存（简化实现）
   */
  private async clearCacheByPattern(pattern: string): Promise<void> {
    try {
      // 由于不同的缓存实现可能不支持模式删除，这里使用简化的实现
      // 在实际项目中，可能需要根据具体的缓存实现来调整
      await this.midwayCache.del(pattern);
    } catch (error) {
      console.warn(`清除缓存模式 ${pattern} 失败:`, error);
    }
  }
}
